#!/usr/bin/perl

use Cwd;
use File::Find;
use File::Path;
use File::Spec;
use Getopt::Long;
use strict;
use warnings;

my @input;
my $output;
my $block = "application/infoblock.h";
my $debug = 0;
my $pcb = "";
my $quiet = 0;
my $help = 0;

my $USAGE=<<EOF;
This script merges input HEX files into output HEX file

Usage: $0 [OPTIONS]

OPTIONS:
  --input=<file>  : input HEX files
  --output=<file> : output HEX file name
  --block=<file>  : infoblock.h file name
  --debug         : merge debug version
  --pcb=<version> : pcb version, a1, a2, a3, ...
  --quiet         : less output
  --help          : show this information
EOF

if (!GetOptions('input=s'   => \@input,
                'output=s'  => \$output,
                'block=s'   => \$block,
                'debug'     => \$debug,
                'pcb=s'     => \$pcb,
                'quiet'     => \$quiet,
                'help'      => \$help )
    || !scalar(@input)
#   || !defined($pcb)
    || !defined($output)
    || $help) {
    print $USAGE;
    exit(1);
}

@input = split(/,/, join(',', @input));

my $cwd = getcwd();

# 读取infoblock.h中的主版本和次版本号, 然后将$outputFile文件名后增加该版本号
# 输入pcb_version, debug_mode
# 返回(主版本, 次版本)
sub parseVersion
{
    my $majorVer;
    my $minorVer;

    my $pcb_ver = uc(shift);
    my $debug_mode = shift;

    my $suffix = $pcb_ver . ($debug_mode ? "_DEBUG" : "");
    my $majorPattern = '^\s*#\s*define\s+(?:APP_FW_VERSION_HIGH|VER_HI_' . $suffix . ')\s+(\d+)';
    my $minorPattern = '^\s*#\s*define\s+(?:APP_FW_VERSION_LOW|VER_LO_' . $suffix . ')\s+(\d+)';

    open(my $in, "<", $block) or die "Can't open $block: $!\n";

    while(<$in>) {
        if (/$majorPattern/) {
            $majorVer = $1;
        } elsif (/$minorPattern/) {
            $minorVer = $1;
        }
    }
    close($in);

    return ($majorVer, $minorVer);
}

# 连接文件名, 除第一参数外, 将所有的参数用"_"连接起来, 插入到第一个参数的扩展名前
sub catFileName
{
    my $filename = shift;
    my $ext = rindex($filename, ".");

    substr $filename, $ext, 1, "_" . join("_", grep($_, @_)) . ".";
    return $filename;
}

# 合并所有的HEX文件
sub mergeFile
{
    my $filename = shift;
    my @outLines;

    print "Merging into $filename\n";

    for(@_) {
        print "  processing $_\n" if !$quiet;
        open(my $in, "<", $_) or die "Can't open $_: $!\n";

        while(<$in>) {
            next if /:00000001FF/;
            push @outLines, $_;
        }

        close($in);
    }
    
    push @outLines, ":00000001FF\n";
    
    open(my $out, ">", $filename) or die "Can't open $filename: $!\n";
    print $out @outLines if !$quiet;
    close($out);
}

# main -----------------------------------------------------

my ($majorVer, $minorVer) = parseVersion $pcb, $debug;

my $target = catFileName $output, $pcb, "$majorVer.$minorVer" . ($debug ? "_d" : "");
mergeFile $target, @input;
